home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / PCTAGS15.ARJ / WILDFILE.C < prev    next >
C/C++ Source or Header  |  1991-09-25  |  9KB  |  353 lines

  1. /*
  2.  EPSHeader
  3.  
  4.    File: wildfile.c
  5.    Author: J. Kercheval
  6.    Created: Thu, 03/14/1991  21:49:02
  7. */
  8. /*
  9.  EPSRevision History
  10.  
  11.    J. Kercheval  Sat, 03/16/1991  15:48:38  add and use FileInfo struct
  12.    J. Kercheval  Sat, 03/16/1991  20:30:52  add status byte and '.' checking
  13.    J. Kercheval  Sat, 03/16/1991  22:50:42  _FA_NORMAL files unique, similar to _FA_READONLY behavior
  14.    J. Kercheval  Thu, 03/28/1991  21:23:37  move DOT_LAST to find_firstfile
  15.    J. Kercheval  Sun, 03/31/1991  14:31:15  change '/' to '\\' in path
  16.    D. Kirschbaum Mon, 05/13/1991  16:42:00  Minor Turbo C changes v1.14
  17. */
  18.  
  19. #include <stdlib.h>
  20. #include <string.h>
  21.  
  22. #include "wildfile.h"
  23. #include "filmatch.h"
  24.  
  25. #ifndef __TURBOC__
  26. #define findfirst(n, a, s) _dos_findfirst(n, s, a)
  27. #define findnext _dos_findnext
  28. #else                           /* __TURBOC__ */
  29. #include <ctype.h>              /* toupper() v1.14 */
  30. #endif
  31.  
  32. #define DOT_LAST 0x01           /* set status byte if last char in pattern is
  33.                                  * '.' */
  34.  
  35. void splitpath(FileInfo * ff);
  36.  
  37.  
  38. /*----------------------------------------------------------------------------
  39. *
  40. *   Start of find_firstfile()
  41. *
  42. ----------------------------------------------------------------------------*/
  43.  
  44. BOOLEAN find_firstfile(FileInfo * ff)
  45. {
  46.     char path[MAXPATH + 1];     /* found file and path */
  47.  
  48.     \
  49.         char *c;                /* temporary pointer variable */
  50.  
  51.     int error_return;           /* error return from is_valid_pattern */
  52.  
  53.     BOOLEAN found;              /* looping flag */
  54.     BOOLEAN dot_found;          /* '.' character checking */
  55.  
  56.     /* empty strings are bummers, aren't they? */
  57.     if (!*(ff->file_pattern)) {
  58.         return FALSE;
  59.     }
  60.  
  61.     /* convert to upper case */
  62.     c = ff->file_pattern;
  63.     while (*c) {
  64.         *c = (char) toupper(*c);
  65.  
  66.         /* if the last pattern char is '.' then set status byte correctly */
  67.         if (*c == '.')
  68.             ff->status |= DOT_LAST;
  69.         else
  70.             ff->status &= ~DOT_LAST;
  71.  
  72.         c++;
  73.     }
  74.  
  75.     /* check for valid pattern string */
  76.     if (!is_valid_pattern(ff->file_pattern, &error_return)) {
  77.         return FALSE;
  78.     }
  79.  
  80.     /* copy the path portion of the pattern to file_path */
  81.     splitpath(ff);
  82.  
  83.     /* create the search path */
  84.     strcpy(path, ff->file_path);
  85.     strcat(path, "*.*");
  86.  
  87.     /* check that the search path will not be too long */
  88.     if (strlen(path) > MAXPATH) {
  89.         return FALSE;
  90.     }
  91.  
  92.     /* obtain the first file conforming to path */
  93.     if (findfirst(path, &(ff->file), (ff->file_attributes) & ~_FA_NORMAL)) {
  94.         return (FALSE);
  95.     }
  96.  
  97.     /* if the file name is empty we want it not */
  98.     if (!*(ff->file.name)) {
  99.         return (FALSE);
  100.     }
  101.  
  102.     /* init looping variable */
  103.     found = FALSE;
  104.  
  105.     /* Build path and file name needed for validation */
  106.     strcpy(path, ff->file_path);
  107.     strcat(path, ff->file.name);
  108.  
  109.     /* Check for '.' if required */
  110.     if (ff->status & DOT_LAST) {
  111.  
  112.         /* init looping variables */
  113.         dot_found = FALSE;
  114.         c = ff->file.name;
  115.  
  116.         /* see if file has extension and give it '.' if not */
  117.         while (*c) {
  118.             if (*c == '.')
  119.                 dot_found = TRUE;
  120.             c++;
  121.         }
  122.         if (!dot_found)
  123.             strcat(path, ".");
  124.     }
  125.  
  126.     /* Verify name and attribute wanted for files */
  127.     if (match(ff->file_pattern, path)) {
  128.  
  129.         if (!ff->file.attributes) {
  130.             if (ff->file_attributes & _FA_NORMAL) {
  131.                 found = TRUE;
  132.             }
  133.         }
  134.         else {
  135.             if (ff->file_attributes & ff->file.attributes) {
  136.                 found = TRUE;
  137.             }
  138.         }
  139.     }
  140.  
  141.     while (!found) {
  142.  
  143.         /* obtain the next file comforming to path */
  144.         if (findnext(&(ff->file))) {
  145.             return (FALSE);
  146.         }
  147.  
  148.         /* if the file name is empty we want it not */
  149.         if (!*(ff->file.name)) {
  150.             return (FALSE);
  151.         }
  152.  
  153.         /* Build path and file name needed for validation */
  154.         strcpy(path, ff->file_path);
  155.         strcat(path, ff->file.name);
  156.  
  157.         /* Check for '.' if required */
  158.         if (ff->status & DOT_LAST) {
  159.  
  160.             /* init looping variables */
  161.             dot_found = FALSE;
  162.             c = ff->file.name;
  163.  
  164.             /* see if file has extension and give it '.' if not */
  165.             while (*c) {
  166.                 if (*c == '.')
  167.                     dot_found = TRUE;
  168.                 c++;
  169.             }
  170.             if (!dot_found)
  171.                 strcat(path, ".");
  172.         }
  173.  
  174.         /* Verify name and attribute wanted for files */
  175.         if (match(ff->file_pattern, path)) {
  176.  
  177.             if (!ff->file.attributes) {
  178.                 if (ff->file_attributes & _FA_NORMAL) {
  179.                     found = TRUE;
  180.                 }
  181.             }
  182.             else {
  183.                 if (ff->file_attributes & ff->file.attributes) {
  184.                     found = TRUE;
  185.                 }
  186.             }
  187.         }
  188.     }
  189.  
  190.     return (TRUE);
  191. }
  192.  
  193.  
  194. /*----------------------------------------------------------------------------
  195. *
  196. *   Start of splitpath()
  197. *       This is a helper function to isolate the pattern from the path.
  198. *       The parameter r gets the path portion of the pattern string p.
  199. *
  200. ----------------------------------------------------------------------------*/
  201.  
  202. void splitpath(FileInfo * ff)
  203. {
  204.     char *last_slash, *c, oldchar;
  205.  
  206.     /* init last_slash and c */
  207.     c = last_slash = ff->file_pattern;
  208.     last_slash--;
  209.  
  210.     /* loop through and find the beginning of the pattern or end of string */
  211.     while (*c && *c != '[' && *c != '*' && *c != '?') {
  212.  
  213.         /* change '/' to '\' */
  214.         if (*c == '/') {
  215.             *c = '\\';
  216.         }
  217.  
  218.         /* if c is a '\' then remember where it is */
  219.         if (*c == '\\') {
  220.             last_slash = c;
  221.         }
  222.  
  223.         /* move to next char in pattern */
  224.         c++;
  225.     }
  226.  
  227.     /* move to next char beyond '\' or to beginning of string */
  228.     last_slash++;
  229.  
  230.     /* store character and make it end of string for now */
  231.     oldchar = *last_slash;
  232.     *last_slash = '\0';
  233.  
  234.     /* copy the beginning of the path to return value */
  235.     strcpy(ff->file_path, ff->file_pattern);
  236.  
  237.     /* restore character */
  238.     *last_slash = oldchar;
  239. }
  240.  
  241.  
  242. /*----------------------------------------------------------------------------
  243. *
  244. *   Start of find_nextfile()
  245. *
  246. ----------------------------------------------------------------------------*/
  247.  
  248. BOOLEAN find_nextfile(FileInfo * ff)
  249. {
  250.     char path[MAXPATH + 1];     /* full filename and path for pattern
  251.                                  * checking */
  252.     char *c;                    /* tempory pointer variable */
  253.  
  254.     BOOLEAN found;              /* looping flag */
  255.     BOOLEAN dot_found;          /* '.' character checking */
  256.  
  257.     found = FALSE;
  258.  
  259.     while (!found) {
  260.  
  261.         /* obtain the next file comforming to path */
  262.         if (findnext(&(ff->file))) {
  263.             return (FALSE);
  264.         }
  265.  
  266.         /* if the file name is empty we want it not */
  267.         if (!*(ff->file.name)) {
  268.             return (FALSE);
  269.         }
  270.  
  271.         /* Build path and file name needed for validation */
  272.         strcpy(path, ff->file_path);
  273.         strcat(path, ff->file.name);
  274.  
  275.         /* Check for '.' if required */
  276.         if (ff->status & DOT_LAST) {
  277.  
  278.             /* init looping variables */
  279.             dot_found = FALSE;
  280.             c = ff->file.name;
  281.  
  282.             /* see if file has extension and give it '.' if not */
  283.             while (*c) {
  284.                 if (*c == '.')
  285.                     dot_found = TRUE;
  286.                 c++;
  287.             }
  288.             if (!dot_found)
  289.                 strcat(path, ".");
  290.         }
  291.  
  292.         /* Verify name and attribute wanted for files */
  293.         if (match(ff->file_pattern, path)) {
  294.  
  295.             if (!ff->file.attributes) {
  296.                 if (ff->file_attributes & _FA_NORMAL) {
  297.                     found = TRUE;
  298.                 }
  299.             }
  300.             else {
  301.                 if (ff->file_attributes & ff->file.attributes) {
  302.                     found = TRUE;
  303.                 }
  304.             }
  305.         }
  306.     }
  307.  
  308.     return (TRUE);
  309. }
  310.  
  311.  
  312. #ifdef TEST
  313.  
  314.  /* The test loop expects the first input parameter on the command line to be
  315.   * the attributes desired in hex format (ie. 0x3f) and the following
  316.   * parameters to be the search path/file name.  Will output the names of all
  317.   * files which match the attributes wanted and the search path/file names. */
  318.  
  319. #include <stdio.h>
  320.  
  321. int main(int argc, char *argv[])
  322. {
  323.     FileInfo ff;
  324.  
  325.     unsigned int tmp;
  326.  
  327.     /* parse the attribute from the command line */
  328.     sscanf(argv[1], "%x", &tmp);
  329.     ff.file_attributes = (unsigned char) tmp;
  330.  
  331.     /* trace down the argument list until all file specs are parsed */
  332.     argc--;
  333.     argv++;
  334.     argc--;
  335.     argv++;
  336.     while (argc > 0) {
  337.         strcpy(ff.file_pattern, *argv);
  338.  
  339.         if (find_firstfile(&ff)) {
  340.             printf("File: %s%s\n", ff.file_path, ff.file.name);
  341.         }
  342.  
  343.         while (find_nextfile(&ff)) {
  344.             printf("File: %s%s\n", ff.file_path, ff.file.name);
  345.         }
  346.         argc--;
  347.         argv++;
  348.     }
  349.     return (0);
  350. }
  351.  
  352. #endif
  353.